package su.samcom.calc.service.util;

import org.springframework.stereotype.Component;
import su.samcom.calc.controller.PriceComparator;
import su.samcom.calc.model.entity.Price;
import su.samcom.calc.service.CalculatorServiceImpl;

import java.util.Collections;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Владислав
 * Date: 24.11.13
 * Time: 18:29
 * To change this template use File | Settings | File Templates.
 */
public class CalculatorUtil {

    public static final CargoParameters TRUCK;
    public static final CargoParameters MIN_GENERAL;
    public static final CargoParameters MIN_SEPARATE;
    /*
    public static final double MIN_GENERAL_CBM = 1;
    public static final double MIN_GENERAL_LENGTH = 0.2;
    public static final double MIN_GENERAL_WEIGHT = 0.1;

    public static final double MIN_SEPARATE_CBM = 8;
    public static final double MIN_SEPARATE_LENGTH = 1.2;
    public static final double MIN_SEPARATE_WEIGHT = 1;*/

    static{
        TRUCK = new CargoParameters();
        TRUCK.setCbm(82.0);
        TRUCK.setLength(13.6);
        TRUCK.setWeight(20.0);

        MIN_GENERAL = new CargoParameters();
        MIN_GENERAL.setCbm(1.0);
        MIN_GENERAL.setLength(0.2);
        MIN_GENERAL.setWeight(0.1);

        MIN_SEPARATE = new CargoParameters();
        MIN_SEPARATE.setCbm(10.0);
        MIN_SEPARATE.setLength(3.0);
        MIN_SEPARATE.setWeight(1.5);
    }

    public static int calculatePrice(int price1, double percent1, int price2, double percent2, double percent){
        return (int) Math.floor((percent - percent1)*(price2-price1)/(percent2 - percent1)+price1);
    }

    public static int calculatePrice(List<Price> prices, double loadedPercent){
        if (prices.size() < 2){
            throw new IllegalArgumentException("Too little Prices. For calculate price, ones must be 2 or more.");
        }
        Collections.sort(prices, new PriceComparator());
        Price price1 = null;
        Price price2 = null;
        for(Price price : prices){
            price1 = price2;
            price2 = price;
            if (calculateLoadedPercent(price) > loadedPercent){
                break;
            }
        }
        if (price1 == null){
            price1 = prices.get(0);
            price2 = prices.get(1);
        }
        int price = calculatePrice(price1.getPrice(),
                                calculateLoadedPercent(price1),
                                price2.getPrice(),
                                calculateLoadedPercent(price2),
                                loadedPercent);
        return price;
    }

    public static double calculateLoadedPercent(Price price){
        CargoParameters cargoParameters = new CargoParameters();
        cargoParameters.setCbm(price.getCbm());
        cargoParameters.setLength(price.getLength());
        cargoParameters.setWeight(price.getWeight());
        return calculateLoadedPercent(cargoParameters);
    }

    public static double calculateLoadedPercent(CargoParameters cargoParameters){
        double cbmPercent = 100 * cargoParameters.getCbm() / TRUCK.getCbm();
        double lengthPercent = 100 * cargoParameters.getLength() / TRUCK.getLength();
        double weightPercent = 100 * cargoParameters.getWeight() / TRUCK.getWeight();
        return Math.max(cbmPercent, Math.max(lengthPercent, weightPercent));
    }

    public static double calculateLoadedPercent(final CargoParameters cargoParameters, CalculatorServiceImpl.CargoType cargoType){
        if (cargoType == CalculatorServiceImpl.CargoType.GENERAL){
            cargoParameters.setCbm(Math.max(cargoParameters.getCbm(), MIN_GENERAL.getCbm()));
            cargoParameters.setLength(Math.max(cargoParameters.getLength(), MIN_GENERAL.getLength()));
            cargoParameters.setWeight(Math.max(cargoParameters.getWeight(), MIN_GENERAL.getWeight()));
        } else if (cargoType == CalculatorServiceImpl.CargoType.SEPARATE){
            cargoParameters.setCbm(Math.max(cargoParameters.getCbm(), MIN_SEPARATE.getCbm()));
            cargoParameters.setLength(Math.max(cargoParameters.getLength(), MIN_SEPARATE.getLength()));
            cargoParameters.setWeight(Math.max(cargoParameters.getWeight(), MIN_SEPARATE.getWeight()));
        }
        return calculateLoadedPercent(cargoParameters);
    }
}
